---
id: taking-photos
title: Taking Photos
sidebar_label: Taking Photos
---

import useBaseUrl from '@docusaurus/useBaseUrl'

<div class="image-container">
  <svg xmlns="http://www.w3.org/2000/svg" width="283" height="535">
    <image href={useBaseUrl("img/demo_capture.gif")} x="18" y="33" width="247" height="469" />
    <image href={useBaseUrl("img/frame.png")} width="283" height="535" />
  </svg>
</div>

## Camera Functions

The Camera provides certain functions which are available through a [ref object](https://reactjs.org/docs/refs-and-the-dom.html):

```tsx
function App() {
  const camera = useRef<Camera>(null)
  // ...

  return (
    <Camera
      ref={camera}
      {...cameraProps}
    />
  )
}
```

To use these functions, you need to wait until the [`onInitialized`](/docs/api/interfaces/CameraProps#oninitialized) event has been fired.

## Taking Photos

To take a photo you first have to enable photo capture:

```tsx
<Camera
  {...props}
  photo={true}
/>
```

Then, simply use the Camera's [`takePhoto(...)`](/docs/api/classes/Camera#takephoto) function:

```ts
const photo = await camera.current.takePhoto()
```

You can customize capture options such as [automatic red-eye reduction](/docs/api/interfaces/TakePhotoOptions#enableautoredeyereduction), [enable flash](/docs/api/interfaces/TakePhotoOptions#flash), [disable the shutter sound](/docs/api/interfaces/TakePhotoOptions#enableshuttersound) and more using the [`TakePhotoOptions`](/docs/api/interfaces/TakePhotoOptions) parameter.

This function returns a [`PhotoFile`](/docs/api/interfaces/PhotoFile) which is stored in a temporary directory and can either be displayed using `<Image>` or `<FastImage>`, uploaded to a backend, or saved to the Camera Roll using [react-native-cameraroll](https://github.com/react-native-cameraroll/react-native-cameraroll).

### Resolution

Photos are always captured in the resolution of the currently selected [`format`](/docs/api/interfaces/CameraProps#format) (See ["Formats"](/docs/guides/formats)).
By default the Camera will select a format with the highest photo resolution available.

If you want to use a custom resolution, configure the Camera to use a format that matches the desired `photoResolution`:

```tsx
const format = useCameraFormat(device, [
  { photoResolution: { width: 1280, height: 720 } }
])

return <Camera {...props} format={format} />
```

### Flash

The [`takePhoto(...)`](/docs/api/classes/Camera#takephoto) function can be configured to enable the [flash](/docs/api/interfaces/TakePhotoOptions#flash) automatically (when the scene is dark), always or never, which will only be used for this specific capture request:

```ts
const photo = await camera.current.takePhoto({
  flash: 'on' // 'auto' | 'off'
})
```

Note that flash is only available on camera devices where [`hasFlash`](/docs/api/interfaces/CameraDevice#hasflash) is `true`; for example most front cameras don't have a flash.

### Quality Balance

The photo capture pipeline can be configured to prioritize speed over quality, quality over speed or balance both quality and speed using the [`qualityBalance`](/docs/api/interfaces/CameraProps#qualitybalance) prop.
If set to `speed`, the Camera pipeline will capture photos faster at the cost of lower quality:

```jsx
return <Camera {...props} qualityBalance="speed" />
```

## Taking Snapshots

In addition to _photo capture_ VisionCamera also supports _snapshot capture_, which can take photos at speeds of up to just 16 milliseconds.
A snapshot is grabbed from the Preview View of the Camera, and will not perform any AE/AF/AWB precapture sequences.

To take a snapshot simply use the Camera's [`takeSnapshot(..)`](/docs/api/classes/Camera#takesnapshot) function:

```ts
const snapshot = await camera.current.takeSnapshot({
  quality: 90
})
```

:::note
On iOS, snapshot capture requires [`video`](/docs/api/interfaces/CameraProps#video) to be enabled.
:::

## Saving the Photo to the Camera Roll

Since the Photo is stored as a temporary file, you need to save it to the Camera Roll to permanentely store it. You can use [react-native-cameraroll](https://github.com/react-native-cameraroll/react-native-cameraroll) for this:

```ts
const file = await camera.current.takePhoto()
await CameraRoll.save(`file://${file.path}`, {
  type: 'photo',
})
```

## Getting the Photo's data

To get the Photo's pixel data, you can use [`fetch(...)`](https://reactnative.dev/docs/network#using-fetch) to read the local file as a Blob:

```ts
const file = await camera.current.takePhoto()
const result = await fetch(`file://${file.path}`)
const data = await result.blob();
```

<br />

#### 🚀 Next section: [Recording Videos](recording-videos)
